Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a synchronous write loop for connections. #1392

Open
wants to merge 1 commit into
base: 6.x
Choose a base branch
from

Conversation

lukebakken
Copy link
Contributor

@lukebakken lukebakken commented Sep 25, 2023

Fixes #1354

Supersedes #1389

Copy link
Contributor

@stebet stebet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good :)

@lukebakken lukebakken force-pushed the rabbitmq-dotnet-client-1389 branch 2 times, most recently from 3a6cbf1 to a905764 Compare September 26, 2023 21:36
@lukebakken lukebakken modified the milestones: 6.6.0, 6.7.0 Sep 28, 2023
@lukebakken lukebakken modified the milestones: 6.7.0, 6.8.0 Nov 15, 2023
@danielmarbach
Copy link
Collaborator

Is this worthwhile pulling in given the direction the client is heading to? To me that looks more like a bandaid that ignores the underlying sync blocking IO. Any configuration flag like this has to be explained to the users to make sure it is used in the right scenarios and then also be maintained and/or deprecated in the right ways.

To me by reading through the conversation thread in the linked issue I couldn't really find derive that this writer loop bandaid will actually solve much in the wild. If the root cause should be fixed wouldn't it then be better to try to backport some of the asyncification from v7 that can be brought in as pure internal potentially to free up the code path from synchronous IO?

@michaelklishin
Copy link
Member

I don't have objections to adopting this for 6.x and moving full steam ahead with much more fundamental changes for 7.x.

The maintainers of this client understand that 6.x has certain fundamental limitations that can be considered unfixable.

There is also a parallel to draw with the Khepri migration in RabbitMQ itself. RabbitMQ 3.x has very old design decisions that only a 4.x can really address. Even though in the end Khepri will be an option in 3.13+, which can be considered a very large "band-aid", all future plans assume a reasonable number of breaking changes exactly because a patchwork of band-aids can only take you so far.

So I vote for merging this and focussing on 7.x. @danielmarbach does this make sense?

@lukebakken lukebakken modified the milestones: 6.8.0, 6.9.0 Dec 5, 2023
/// timeouts if a large number of blocking requests are going out simultaneously. Will become obsolete
/// once requests become asynchronous. Defaults to false.
/// </summary>
public bool EnableSynchronousWriteLoop { get; set; } = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the default value is false, maybe we could remove the init value

Suggested change
public bool EnableSynchronousWriteLoop { get; set; } = false;
public bool EnableSynchronousWriteLoop { get; set; }

Copy link
Member

@michaelklishin michaelklishin Jan 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making the default more visible is a good idea. I'd not remove it.

Copy link
Contributor

@WeihanLi WeihanLi Feb 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, I think it's a kind of code style. I prefer to remove it while I would not argue for this.

Have a test on this, the default value would be removed when built in release mode, but would not when in debug mode

if (_enableSynchronousWriteLoop)
{
TaskCreationOptions tco = TaskCreationOptions.LongRunning | TaskCreationOptions.DenyChildAttach;
_writerTask = Task.Factory.StartNew(SynchronousWriteLoop, CancellationToken.None, tco, TaskScheduler.Default);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@WeihanLi WeihanLi Feb 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When just using the Task.Run, the thread would be borrowed from the thread pool, the long-running task on a thread-pool thread would affect the thread-pool thread scheduling.
Here's the LongRunning flag is specified, it would use a separate thread, so I think it's ok.

https://github.com/dotnet/runtime/blob/93381bf9c745e5925fb68ac4da2b38526b36222a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs#L42

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants